<template>
    <div class="upload-box">
        <el-upload ref="upload" action="" :auto-upload="false" :on-change="handleChange" :multiple="true" :show-file-list="false" v-bind="uploadConfig">
            <el-button slot="trigger" type="primary">选取文件</el-button>
            <!-- <el-button style="margin-left: 10px;" size="mini" type="success" @click="submitUpload">上传</el-button> -->
            <div slot="tip" class="el-upload__tip">
                <template v-if="uploadConfig.accept">
                    只能上传{{uploadConfig.accept}}文件,
                </template>
                <template v-if="uploadConfig.size">
                    大小不超过{{uploadConfig.size}}M
                </template>
            </div>
        </el-upload>
        <uploadProgress v-model="fileList" :urlVal="urlVal" :nameVal="nameVal" />
    </div>
</template>

<script>
import OSS from "ali-oss"
import uploadProgress from "./uploadProgress.vue"
import emitter from 'element-ui/src/mixins/emitter'
export default {
    mixins: [emitter],
    model: {
        prop: 'fileList',
        event: 'change'
    },
    props: {
        fileList: {
            default: () => [],
            type: Array
        },
        uploadConfig: {
            default () {
                return {}
            },
            type: Object
        }
    },
    data () {
        return {
            ossConfig: {
                region: "1111",
                accessKeyId: "222",
                accessKeySecret: "222",
                bucket: "333",
                ossUrl: '111'
            },
            client: null,
            urlVal: 'url',
            nameVal: 'name'
        };
    },
    created () {
        if (this.uploadConfig.urlVal) this.urlVal = this.uploadConfig.urlVal
        if (this.uploadConfig.nameVal) this.nameVal = this.uploadConfig.nameVal
        this.fileList.forEach(item => {
            if (item[this.urlVal] && item.status === undefined) {
                item.status = "success"
                item.percentage = 100
                item.uid = new Date().getTime();
            }
        })
    },
    methods: {
        async submitUpload () {
            this.init();
            //需要上传的数据
            let UploadList = this.fileList.filter(item => item.status === 'ready' || item.status === 'error');
            try {
                // 等待全部上传成功
                await Promise.all(
                    UploadList.map(item => {
                        item.status = 'upload'
                        return this.multipartUpload(item);
                    })
                )
                return Promise.resolve(true)
            } catch (error) {
                // 上传失败 重置状态
                UploadList.map(item => {
                    if (item.status === 'upload') {
                        item.status = 'error'
                    }
                })
                return Promise.reject(error)
            }

        },
        init () {
            if (!this.client) {
                this.client = new OSS(this.ossConfig);
            }
        },
        //添加文件
        handleChange (file) {
            //没有用element的文件列表 直接清除防止无法无法选取文件
            this.$refs.upload.clearFiles();
            // 判断文件数量
            if (this.uploadConfig.limit && this.fileList.length >= this.uploadConfig.limit && file.status === 'ready') {
                this.$message.warning(`只能上传${this.uploadConfig.limit}个文件`);
                return false
            }
            //判断文件类型
            if (this.uploadConfig.accept && !this.uploadConfig.accept.includes(file.name.split(".").pop())) {
                this.$message.warning(`只能上传${this.uploadConfig.accept.split(',').join(' ')}的文件`);
                return false
            }
            //判断文件大小
            if (this.uploadConfig.size && file.size / 1024 / 1024 > this.uploadConfig.size) {
                this.$message.warning(`文件不能大于${this.uploadConfig.size}M`);
                return false
            }
            if (file.status === "ready") {
                console.log(file);
                if (this.nameVal !== 'name') {
                    file[this.nameVal] = file.name
                }
                this.fileList.push({ ...file })
                // 解决校验后重新输入错误信息还在的问题
                this.dispatch('ElFormItem', 'el.form.change', this.fileList)
            }
        },
        // 上传文件
        async multipartUpload (item) {
            let _this = this
            let url = this.queryRandowFilePath(item.name)
            try {
                const result = await this.client.multipartUpload(url, item.raw, {
                    progress: function (p, checkpoint) {
                        item.percentage = parseInt(p * 100)
                        console.log(item.percentage);
                        if (item.percentage === 100) {
                            item.status = 'success'
                            item[_this.urlVal] = url
                        }
                        // 断点记录点。浏览器重启后无法直接继续上传，您需要手动触发上传操作。
                        item.tempCheckpoint = checkpoint;
                    },
                })
                return Promise.resolve(item)
            } catch (error) {
                return Promise.reject(error)
            }
        },
        // 生成文件相对路径
        queryRandowFilePath (fileName) {
            let chars = "abcdefghijklmnopqrstuvwxyz0123456789";
            let filePath = 'hd-study/upload/';
            for (let i = 0; i < 3; i++) {
                let num1 = Math.floor(Math.random() * 36);
                let num2 = Math.floor(Math.random() * 36);
                filePath += chars.charAt(num1) + chars.charAt(num2) + "/";
            }
            let fileType = fileName.split(".")[1];
            let date = new Date();
            filePath +=
                date.getFullYear() +
                "" +
                (date.getMonth() + 1) +
                "" +
                date.getDate() +
                "_" +
                Math.floor(Math.random() * 99999 + 1) +
                "." +
                fileType;

            return filePath;
        },
    },
    components: {
        uploadProgress
    }
}
</script>